--
-- DESCRIPTION
--
-- @COMPANY **
-- @AUTHOR **
-- @DATE ${date} ${time}
--

---@type AIC_Enemy_C
local M = UnLua.Class()

local ActionCharClass = UE.UClass.Load("/ActionPlatformer/Blueprints/Characters/BP_ActionChar.BP_ActionChar_C")
local KismetMathLibrary = UE.UKismetMathLibrary
-- function M:Initialize(Initializer)
-- end

-- function M:UserConstructionScript()
-- end

function M:ReceiveBeginPlay()

    self:InitializeBindings()

    if self.BTAsset and self.BBAsset then
        self:UseBlackboard(self.BBAsset)
        self:RunBehaviorTree(self.BTAsset)
        --local PlayerPawn = UE.UGameplayStatics.GetPlayerPawn(self, 0)
        --local Target = PlayerPawn:Cast(ActionCharClass)
        ---- print(Target:GetName())
        --self:SetAttackTarget(Target)
    end

    --- 上一帧的速度
    self.LastVelocity = UE.FVector()

end

--- 初始化绑定
function M:InitializeBindings()
    self.AIPerception.OnTargetPerceptionUpdated:Add(self, self.PerceptionUpdated)
end

-- 获取控制器的时候
function M:ReceivePossess(PossessedPawn)
    self.ActionChar = PossessedPawn:Cast(ActionCharClass)
    self.ActionChar.StunStateChanged:Add(self, self.StunStateChanged)
end

--- 眩晕状态改变
function M:StunStateChanged(IsStunned)
    self.Blackboard:SetValueAsBool(self.IsStunnedKey, IsStunned)
end

-- function M:ReceiveEndPlay()
-- end

function M:ReceiveTick(DeltaSeconds)
    self:SetFocusDirection()
end

-- function M:ReceiveAnyDamage(Damage, DamageType, InstigatedBy, DamageCauser)
-- end

-- function M:ReceiveActorBeginOverlap(OtherActor)
-- end

-- function M:ReceiveActorEndOverlap(OtherActor)
-- end

--- 设置攻击目标
function M:SetAttackTarget(AttackTarget)
    self.AttackTarget = AttackTarget

    self.Blackboard:SetValueAsObject(self.AttackTargetKey, self.AttackTarget)
end

--- 设置焦点方向
function M:SetFocusDirection()

    --- 自身是否可以行动
    if not self.ActionChar:CanAct() then
        return
    end

    -- 没有目标或者不可以行动
    local Rotation = UE.FRotator()
    -- 看向位置
    local WatchLocation = UE.FVector()

    --- 判断目标是否有效和能否看到
    if not self.AttackTarget or self.AttackTarget.IsDefeated or not self.SeeThePlayer then
        local TempVelocity = self.ActionChar:GetVelocity()
        local Length = KismetMathLibrary.VSize(TempVelocity)
        if Length <= 10 then
            Rotation = KismetMathLibrary.Conv_VectorToRotator(self.LastVelocity)
            WatchLocation = self.ActionChar:K2_GetActorLocation() + RotationForward(Rotation)
            self:K2_SetFocalPoint(WatchLocation)
            return
        end

        self.LastVelocity = TempVelocity
        Rotation = KismetMathLibrary.Conv_VectorToRotator(self.LastVelocity)
        WatchLocation = self.ActionChar:K2_GetActorLocation() + RotationForward(Rotation)
        self:K2_SetFocalPoint(WatchLocation)
        return

    end

    Rotation = KismetMathLibrary.FindLookAtRotation(self.ActionChar:K2_GetActorLocation(), self.AttackTarget:K2_GetActorLocation())

    WatchLocation = self.ActionChar:K2_GetActorLocation() + RotationForward(Rotation)
    -- UE.UKismetSystemLibrary.DrawDebugSphere(self, WatchLocation, 20, 12, UE.FLinearColor(0, 1, 0, 1), 0.05, 1)
    self:K2_SetFocalPoint(WatchLocation)

end

--- 旋转的向量
---@param Rotation FRotator 旋转
---@return FVector
function RotationForward(Rotation)
    return UE.FVector(KismetMathLibrary.GetForwardVector(Rotation).X, 0, 0) * 100
end

--- 感知更新
---@param Actor AActor
---@param Stimulus FAIStimulus
function M:PerceptionUpdated(Actor, Stimulus)
    local AISense = UE.UAIPerceptionSystem.GetSenseClassForStimulus(self, Stimulus)
    if AISense == UE.UAISense_Sight:StaticClass() then
        self:SightPerception(Actor, Stimulus)
    end
    if AISense == UE.UAISense_Damage:StaticClass() then
        self:DamagePerception(Actor, Stimulus)
    end

end

--- 视力感知
---@param Actor AActor
---@param Stimulus FAIStimulus      人工智能的刺激
function M:SightPerception(Actor, Stimulus)
    self.AttackTarget = Actor:Cast(ActionCharClass)
    if self.AttackTarget and self.AttackTarget.Faction ~= self.ActionChar.Faction and not self.AttackTarget.IsDefeated then

        self.SeeThePlayer = Stimulus.bSuccessfullySensed

        if Stimulus.bSuccessfullySensed then
            self.Blackboard:SetValueAsBool("SeeThePlayer", true)
            -- print("看到了")
            self:SetAttackTarget(self.AttackTarget)
        else
            self.Blackboard:SetValueAsBool("SeeThePlayer", false)
            --  print("看不到了")
            self:SetAttackTarget(nil)
        end
    end
end

--- 伤害感知
---@param Actor AActor
---@param Stimulus FAIStimulus      人工智能的刺激
function M:DamagePerception(Actor, Stimulus)
    print("受到伤害了")
end

return M
